package com.vcs.dao;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;

import org.apache.commons.collections.list.SetUniqueList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import com.googlecode.s2hibernate.struts2.plugin.annotations.SessionTarget;
import com.googlecode.s2hibernate.struts2.plugin.annotations.TransactionTarget;
import com.vcs.domain.Job;
import com.vcs.domain.JobApplication;
import com.vcs.domain.Jobseeker;

public class JobseekerDAOImpl implements JobseekerDAO {

	Log log = LogFactory.getLog(JobseekerDAOImpl.class);

	@SessionTarget
	Session session;

	@TransactionTarget
	Transaction transaction;

	@Override
	public void delete(Long jobseekerId) {
		try {
			Jobseeker jobseeker = (Jobseeker) session.get(Jobseeker.class,
					jobseekerId);
			session.delete(jobseeker);
		} catch (Exception e) {
			transaction.rollback();
			e.printStackTrace();
		}
	}

	@Override
	public List<Jobseeker> listJobseeker() {
		List<Jobseeker> jobseeker = null;
		try {
			jobseeker = session.createQuery("from Jobseeker").list();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return jobseeker;
	}

	// Get jobseeker by ID.
	@Override
	public Jobseeker listJobseekerById(Long jobseekerId) {
		log.info("listJoseekerById()...");
		log.info("Fetching data for jobseekerId : " + jobseekerId);
		Jobseeker jobseeker = null;
		try {
			jobseeker = (Jobseeker) session.get(Jobseeker.class, jobseekerId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.info(jobseeker);
		return jobseeker;
	}

	@Override
	public Jobseeker getProfileByUsername(String username, String password) {
		Jobseeker jobseeker = null;
		try {
			log.info("inside try block of getProfileByUsername() method");
			Criteria crit = session.createCriteria(Jobseeker.class)
					.add(Restrictions.like("username", username))
					.add(Restrictions.like("password", password));
			List prof = crit.list();
			jobseeker = (Jobseeker) prof.get(0);
		} catch (Exception e) {
			log.info("!!!!!!!!!!! inside catch block.. Transaction rollback.");
			transaction.rollback();
			e.printStackTrace();
		} finally {
			/*
			 * if(session != null){ transaction.commit(); session.close(); }
			 */
		}
		log.info("Jobseeker retrieved from database is : " + jobseeker);
		return jobseeker;

	}

	@Override
	public void save(Jobseeker jobseeker) {
		log.info("JobseekerDaoImpl.save()...");
		try {
			session.save(jobseeker);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void update(Jobseeker jobseeker) {
		log.info("jobseekerDaoImpl.update()...");
		try {
			session.update(jobseeker);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void updateResumeName(String resumeName, Long jobseekerId) {
		log.info("updateResumeName()...");
		try {
			log.info("method parameters are : [" + resumeName + " , "
					+ jobseekerId + "]");
			log.info("Hibernate session is : " + session);
			Jobseeker jobseeker = (Jobseeker) session.get(Jobseeker.class,
					jobseekerId);
			log.info(jobseeker);
			jobseeker.setResumeName(resumeName);
			jobseeker.setResumeUploadDate(new java.util.Date());

			session.update(jobseeker);

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void applyJob(JobApplication jobApplication) {
		log.info("JobseekerDAOImpl.applyJob()...");
		try {
			session.save(jobApplication);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Job> getJobAppliedByMe(Long jobseekerId) {
		log.info("getJobAppliedByMe()...");
		
		List<Long> uniqueJobList = getAppliedJobIdList(jobseekerId);

		String str = "";
		for (Long l : uniqueJobList) {
			str = str + l + ",";
		}
		// log.info("str: " + str);
		List<Job> jobList = null;
		if (str.length() > 1) {
			str = str.substring(0, str.length() - 1);
			log.info("str: " + str);
			String jobHql = "from Job job where job.jobId in (" + str + ")";
			log.info("HQL is: " + jobHql);
			jobList = session.createQuery(jobHql).list();
			log.info("JobList: " + jobList);
		}
		return jobList;
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Long> getAppliedJobIdList(Long jobseekerId) {
		String hql = "select jobId from JobApplication where jobseekerId="
				+ jobseekerId;
		List<Long> jobAppliedList = session.createQuery(hql).list();
		// log.info("Jobs applied by jobAppliedList: " + jobAppliedList);
		List<Long> uniqueJobList = jobAppliedList;
		log.info("Jobs applied by jobseeker no: " + jobseekerId + " are "
				+ uniqueJobList);
		return uniqueJobList;
	}

	@Override
	public Jobseeker getProfileById(Long jobseekerId) {
		Jobseeker js = (Jobseeker) session.get(Jobseeker.class, jobseekerId);
		return js;
	}

	@Override
	public List<String> getAllUsernames() {

		log.info("getAllUsernames()...");
		// TODO Fix this function. duplicate usernames should not get
		// registered.
		log.info("Hibernate session is :" + session);
		List<String> usernamesList = null;
		try {
			usernamesList = session.createQuery(
					"select j.username from Jobseeker j").list();
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.info("Jobseeker usernames List ==>: " + usernamesList);
		return usernamesList;
	}

	@Override
	public List<String> getAllEmailIds() {

		List<String> allEmailIds = session.createSQLQuery(
				"select j.email from jobseekers as j").list();
		log.info("allEmailIds " + allEmailIds);
		return allEmailIds;
	}

	/**
	 * Gets returns user name and password RETURNS returns a String[] containing
	 * user name and password
	 */

	@Override
	public String[] getUsernameAndPassword(String emailId) {
		String sql = "select j.username, j.password from jobseekers j where j.email='"
				+ emailId + "'";
		log.info("sql" + sql);
		List credentialsList = session.createSQLQuery(sql).list();
		// log.info(credentialsList);
		Object[] objArr = (Object[]) credentialsList.get(0);

		String[] credentials = new String[2];
		// log.info("------------" + credentialsList.get(0));
		// log.info("credentialsList.size() : "+credentialsList.size());

		credentials[0] = objArr[0].toString();
		credentials[1] = objArr[1].toString();

		return credentials;
	}
}
